﻿using DDLParser.constant;
using DDLParser.model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DDLParser.sqlserver
{
    class SqlServerProcessor : IDDLProcessor
    {
        List<ClassSchema> result;
        Stack<ParserStack> wordStack;
        SqlServerTermLookup termLookup;
        int doTag;
        int doStatus;
        List<string> errorMessage;
        ClassSchema currentClass;
        AttributeSchema currentAttribute;
        SqlServerTypeLookup dataTypeLookup;
        SqlServerDataValueLookup dataValueLookup;
        bool isCommaAttribute = false;
        bool isPrimary = false;
        bool isNot = false;
        bool isOpenParenthesis = false;
        bool isON = false;
        bool isConstraint = false;
        bool isNumber = false;
        bool isForeign = false;
        bool isOpenLineComment = false;
        bool isOpenMultiLineComment = false;
        int commentType = 0;
        string foreignKeyClassName = "";

        public SqlServerProcessor()
        {
            result = new List<ClassSchema>();
            wordStack = new Stack<ParserStack>();
            termLookup = new SqlServerTermLookup();
            errorMessage = new List<string>();
            dataTypeLookup = new SqlServerTypeLookup();
            dataValueLookup = new SqlServerDataValueLookup();

            doTag = SqlServerStatus.UNKNOWN;
            doStatus = SqlServerStatus.UNKNOWN;
        }

        public List<ClassSchema> GetResult()
        {
            return result;
        }

        public void DoWord(DDLWord word)
        {
            int termType = termLookup.GetType(word);
            bool isSkipComment = (isOpenLineComment || isOpenMultiLineComment)? true:false;
            bool isCommentType = false;
            if (word.Word == SqlServerTerminator.HYPHEN ||
                word.Word == SqlServerTerminator.SLASH ||
                word.Word == SqlServerTerminator.ASTERISK||word.Word=="\r\n")
            {
                isCommentType = true;
            }
            else
            {
                if (commentType != CommentType.UNKNOWN)
                {
                    commentType = CommentType.UNKNOWN;
                }
            }

            if (isSkipComment && !isCommentType)
            {
                return;
            }


            if (termType == SqlServerTermType.CREATE)
            {
                DoCreateTag(word);
            }
            else if (termType == SqlServerTermType.ALTER)
            {
                DoAlterTag(word);
            }
            else if (termType == SqlServerTermType.PROCEDURE)
            {
                DoProcedureTag(word);
            }
            else if (termType == SqlServerTermType.END)
            {
                DoEndTag(word);
            }
            else if (doTag == SqlServerStatus.TAG_PROCEDURE)
            {

            }
            else if (termType == SqlServerTermType.TABLE)
            {
                if (doTag == SqlServerStatus.TAG_CREATE)
                {
                    DoTableTag(word);
                }
                else if (doTag == SqlServerStatus.TAG_ALTER)
                {
                    DoAlterTableTag(word);//change doStatus = REQUIRE_ALTER_TABLE_NAME
                }
                else if (doTag == SqlServerStatus.TAG_PROCEDURE)
                {

                }
            }        
            else if (termType == SqlServerTermType.IDENTITY)/*add condition term type    */
            {
                DoAutoIncrementTag(word);
            }
            else if (termType == SqlServerTermType.NOT)/*add condition term type    */
            {
                DoNotTag(word);
            }
            else if (termType == SqlServerTermType.NULL)/*add condition term type    */
            {
                DoNotNullTag(word);
            }
            else if (termType == SqlServerTermType.PRIMARY)/*add condition term type    */
            {
                DoPkTag(word);
            }
            else if (termType == SqlServerTermType.KEY)/*add condition term type    */
            {
                isConstraint = false;
                if (doTag == SqlServerStatus.TAG_PRIMARY)
                {
                    doStatus = SqlServerStatus.SCRIPT_ATTRIBUTE;
                    DoPrimaryKeyTag(word);
                }
                else if (doTag == SqlServerStatus.TAG_ALTER && doStatus == SqlServerStatus.REQUIRE_ALTER_OPTION)
                {
                    DoForeigntTag(word);
                }
            }
            else if (termType == SqlServerTermType.CONSTRAINT)/*add condition term type    */
            {

                if (doTag == SqlServerStatus.TAG_ATTRIBUTE)
                {
                    isConstraint = true;
                    doStatus = SqlServerStatus.SCRIPT_ATTRIBUTE;
                }
            }
            else if (termType == SqlServerTermType.ON)/*add condition term type    */
            {
                isON = true;
            }
            else if (termType == SqlServerTermType.FOREIGN)/*add condition term type    */
            {
                isForeign = true;
            }
            else
            {
                DoUnknowTag(word);
            }
        }

        private void DoCreateTag(DDLWord word)
        {
            ParserStack parser = new ParserStack();
            parser.Word = word;
            //if (word.Word == "(")
            //{
            //    parser.Type = SqlServerStackType.CREATETABLE_PARENTHESIS;
            //}
            wordStack.Push(parser);
            doTag = SqlServerStatus.TAG_CREATE;
            doStatus = SqlServerStatus.REQUIRE_CREATE_PARAMETER;
        }

        private void DoTableTag(DDLWord word)
        {
            if (doTag != SqlServerStatus.TAG_CREATE)
            {
                return;
            }

            if (doStatus != SqlServerStatus.REQUIRE_CREATE_PARAMETER)
            {
                errorMessage.Add("Error : TABLE tag is not follow by CREATE Tag : Line:" + word.LineNumber + " Offset:" + word.LineOffset);
                return;
            }

            currentClass = new ClassSchema();
            currentClass.Attributes = new List<AttributeSchema>();
            result.Add(currentClass);
            doStatus = SqlServerStatus.REQUIRE_CREATE_NAME;
        }

        private void DoProcedureTag(DDLWord word)
        {
            if (doStatus == SqlServerStatus.REQUIRE_CREATE_PARAMETER)
            {
                doTag = SqlServerStatus.TAG_PROCEDURE;
                doStatus = SqlServerStatus.REQUIRE_CREATE_PROCEDURE;
            }
           
        }

        private void DoEndTag(DDLWord word)
        {
            if (doStatus == SqlServerStatus.REQUIRE_CREATE_PROCEDURE)
            {
                wordStack.Pop();
                doStatus = SqlServerStatus.UNKNOWN;
                doTag = SqlServerStatus.UNKNOWN;
            }

        }
        private void DoGoTag(DDLWord word)
        {
            if (doStatus == SqlServerStatus.REQUIRE_ALTER_OPTION)
            {
                wordStack.Pop();
                doStatus = SqlServerStatus.UNKNOWN;
                doTag = SqlServerStatus.UNKNOWN;
            }

        }

        private void DoAutoIncrementTag(DDLWord word)
        {
            if (doStatus == SqlServerStatus.REQUIRE_ATTRIBUTE_OPTION)
            {
                    currentAttribute.AutoIncrement = true;
                    doStatus = SqlServerStatus.REQUIRE_AUTOINCREMENT_OPTION;
                
                
                //doTag = SqlServerStatus.TAG_ATTRIBUTE;
            }

        }

        private void DoNotTag(DDLWord word)
        {
                isNot = true;
        }

        private void DoNotNullTag(DDLWord word)
        {
            if ((doTag == SqlServerStatus.TAG_ATTRIBUTE) && isNot)
            {
                currentAttribute.Nullable = false;
                doStatus = SqlServerStatus.REQUIRE_ATTRIBUTE_OPTION;
                isNot = false;
            }
            else
            {
                currentAttribute.Nullable = true;
                doStatus = SqlServerStatus.REQUIRE_ATTRIBUTE_OPTION;
            }
        }

        private void DoPkTag(DDLWord word)
        {
            if (isON)
            {
                return;
            }
            if (word.Word == SqlServerTerm.PRIMARY || word.Word == SqlServerTerm._PRIMARY && doTag ==SqlServerStatus.TAG_ATTRIBUTE)
            {
                isPrimary = true;
                doTag = SqlServerStatus.TAG_PRIMARY;
            }
        }

        private void DoPrimaryKeyTag(DDLWord word)
        {
            if (word.Word == SqlServerTerm._KEY && (doTag == SqlServerStatus.TAG_PRIMARY) && isPrimary)
            {
                currentAttribute.Pk = true;
                doTag = SqlServerStatus.TAG_ATTRIBUTE;
                doStatus = SqlServerStatus.REQUIRE_ATTRIBUTE_OPTION;
            }
            else if ((doTag == SqlServerStatus.TAG_PRIMARY) && isPrimary)
            {
                doStatus = SqlServerStatus.REQUIRE_PRIMARY;
            }   
        }

        private void DoForeigntTag(DDLWord word)
        {
            if ((doTag == SqlServerStatus.TAG_ALTER) && isForeign)
            {
                doStatus = SqlServerStatus.REQUIRE_FOREIGNKEY;
            }
        }

        private void DoAlterTag(DDLWord word)
        {
            ParserStack parser = new ParserStack();
            parser.Word = word;
            
            wordStack.Push(parser);
            doTag = SqlServerStatus.TAG_ALTER;
            doStatus = SqlServerStatus.REQUIRE_ALTER_TABLE;
        }

        private void DoAlterTableTag(DDLWord word)
        {
            doStatus = SqlServerStatus.REQUIRE_ALTER_TABLE_NAME;
        }

        private void DoUnknowTag(DDLWord word)
        {
            if (word.Word == SqlServerTerminator.HYPHEN)
            {
                if (commentType == CommentType.HYPHEN)
                {
                    //DoLineCommentTag(word);
                    isOpenLineComment = true;
                    commentType = CommentType.UNKNOWN;
                }
                else
                {
                    commentType = CommentType.HYPHEN;
                }

            }
            else if (word.Word == SqlServerTerminator.SLASH)
            {
                if (commentType == CommentType.ASTERISK)
                {
                    isOpenMultiLineComment = false;
                    commentType = CommentType.UNKNOWN;
                }
                else
                {
                    commentType = CommentType.SLASH;
                }
                //DoMultiLineCommentTag(word);
                //isOpenMultiLineComment = true;
            }
            else if (word.Word == SqlServerTerminator.ASTERISK)
            {
                if (commentType == CommentType.SLASH)
                {
                    isOpenMultiLineComment = true;
                    commentType = CommentType.UNKNOWN;
                }
                else
                {
                    //DoMultiLineCommentTag(word);
                    commentType = CommentType.ASTERISK;
                }
            }
            else if (word.Word=="\r\n")/*Check Return */
            {
                isON = false;
                DoReturnTag(word);
            }
            else if (word.TerminatorType == DDLTerminatorType.TAB)
            {
                isON = false;
                //Do not thing
            }
            else if (doStatus == SqlServerStatus.REQUIRE_CREATE_NAME)
            {
                DoCreateTableNameTag(word);
            }
            else if (doStatus == SqlServerStatus.REQUIRE_BEGIN_ATTRIBUTE)
            {
                DoCreateAttributeTag(word);
            }
            else if (doStatus == SqlServerStatus.REQUIRE_ATTRIBUTE_NAME)
            {
                DoAttributeNameTag(word);
            }
            else if (doStatus == SqlServerStatus.REQUIRE_ATTRIBUTE_DATATYPE)
            {
                DoDataTypeNameTag(word);
            }
            else if (doStatus == SqlServerStatus.REQUIRE_ATTRIBUTE_LENGTH_DATATYPE)
            {
                DoLengthDataTypeTag(word);
            }
            else if (doStatus == SqlServerStatus.REQUIRE_AUTOINCREMENT_OPTION)
            {
                DoAutoIncrementOptionTag(word);
            }
            else if (doStatus == SqlServerStatus.REQUIRE_ATTRIBUTE_OPTION)
            {
                DoOptionTag(word);
            }
            else if (doStatus == SqlServerStatus.REQUIRE_PRIMARY)
            {
                DoPkAttributeTag(word);
            }
            else if (doStatus == SqlServerStatus.SCRIPT_ATTRIBUTE)
            {
                
            }
            else if (doStatus == SqlServerStatus.REQUIRE_ALTER_TABLE)
            {
                
            }
            else if (doStatus == SqlServerStatus.REQUIRE_ALTER_TABLE_NAME)
            {
                DoCreateAlterTableNameTag(word);
            }
            else if (doStatus == SqlServerStatus.REQUIRE_ALTER_OPTION)
            {
                
            }
            else if (doStatus == SqlServerStatus.REQUIRE_FOREIGNKEY)
            {
                DoForigntAttributeTag(word);
            }
            else if (doStatus == SqlServerStatus.REQUIRE_CREATE_PROCEDURE)
            {

            }
            else
            {
                //int checkword = wordStack.Count();
                //if (checkword != 0)
                //{
                //    wordStack.Pop();
                //}
            }

            if (commentType == CommentType.UNKNOWN)
            {
                //return;
            }

            if ((word.Word != SqlServerTerminator.HYPHEN) &&
                (word.Word != SqlServerTerminator.SLASH) &&
                (word.Word != SqlServerTerminator.ASTERISK))
            {
                commentType = CommentType.UNKNOWN;
            }
        }

        //private void DoLineCommentTag(DDLWord word)
        //{
        //    isOpenLineComment = true;
        //}

        //private void DoMultiLineCommentTag(DDLWord word)
        //{
        //    if (!isOpenMultiLineComment)
        //    {
        //        isOpenMultiLineComment = true;
        //    }
        //}

        private void DoCreateTableNameTag(DDLWord word)
        {
            if (currentClass == null)
            {
                return;
            }

            string[] nameList = word.Word.Split('.');
            int numName = nameList.Length;

            string tableName = nameList[numName - 1];

            // delete '[' and ']'
            var removeList = new string[] { "[", "]" };
            foreach (var removeChar in removeList)
            {
                tableName = tableName.Replace(removeChar, string.Empty);
            }

            if (tableName.Length <= 0)
            {
                errorMessage.Add("Error : TABLE name is empty : Line:" + word.LineNumber + " Offset:" + word.LineOffset);
                return;
            }

            currentClass.ClassName = tableName;
            doStatus = SqlServerStatus.REQUIRE_BEGIN_ATTRIBUTE;
        }

        private void DoAttributeNameTag(DDLWord word)
        {
            if (currentClass == null || isConstraint)
            {
                return;
            }
            
            string[] nameList = word.Word.Split('.');
            int numName = nameList.Length;

            string attributeName = nameList[numName - 1];

            // delete '[' and ']'
            var removeList = new string[] { "[", "]" };
            foreach (var removeChar in removeList)
            {
                attributeName = attributeName.Replace(removeChar, string.Empty);
            }

            if (attributeName.Length <= 0)
            {
                errorMessage.Add("Error : TABLE name is empty : Line:" + word.LineNumber + " Offset:" + word.LineOffset);
                return;
            }

            currentAttribute.Name = attributeName;
            doStatus = SqlServerStatus.REQUIRE_ATTRIBUTE_DATATYPE;
        }

        private void DoDataTypeNameTag(DDLWord word)
        {
            if (currentAttribute == null)
            {
                return;
            }

            string[] nameList = word.Word.Split('.');
            int numName = nameList.Length;

            string datatypeName = nameList[numName - 1];

            // delete '[' and ']'
            var removeList = new string[] { "[", "]" };
            foreach (var removeChar in removeList)
            {
                datatypeName = datatypeName.Replace(removeChar, string.Empty);
            }

            if (datatypeName.Length <= 0)
            {
                errorMessage.Add("Error : TABLE name is empty : Line:" + word.LineNumber + " Offset:" + word.LineOffset);
                return;
            }

            DDLWord ddlWord = new DDLWord();
            ddlWord.Word = datatypeName;
            int type = dataTypeLookup.GetType(ddlWord);
            if (type == DDLTermType.UNKNOWN)
            {
                errorMessage.Add("Error : Unknown DataType : Line:" + word.LineNumber + " Offset:" + word.LineOffset);
                doStatus = SqlServerStatus.SCRIPT_ATTRIBUTE;
            }
            currentAttribute.DataType = type;
            if (type == DataType.STRING)
            {
                doStatus = SqlServerStatus.REQUIRE_ATTRIBUTE_LENGTH_DATATYPE;
            }
            else
            {
                doStatus = SqlServerStatus.REQUIRE_ATTRIBUTE_OPTION;
            }
        }

        private void DoCreateAttributeTag(DDLWord word)
         {
            if (word.Word != SqlServerTerminator.OPEN_PARENTHESIS)
            {
                return;
            }
            ParserStack parser = new ParserStack();
            parser.Word = word;
            if (word.Word == "(")
            {
                parser.Type = SqlServerStackType.CREATETABLE_PARENTHESIS;
            }
            wordStack.Push(parser);
            currentAttribute = new AttributeSchema();
            doTag = SqlServerStatus.TAG_ATTRIBUTE;
            doStatus = SqlServerStatus.REQUIRE_ATTRIBUTE_NAME;
        }

        private void DoOptionTag(DDLWord word)
        {
            //ParserStack checkword;
            //DDLWord ddlWord;
            //ddlWord.Word = SqlServerTerminator.OPEN_PARENTHESIS;
            //ParserStack checkword.Word = ddlWord;
            if (word.Word == SqlServerTerminator.COMMA)
            {
                isCommaAttribute = true;
            }
            else if (word.Word == SqlServerTerminator.OPEN_PARENTHESIS)
            {
                ParserStack parser = new ParserStack();
                parser.Word = word;
                wordStack.Push(parser);
            }
            else if (word.Word == SqlServerTerminator.CLOSE_PARENTHESIS)
            {
                ParserStack parser = new ParserStack();
                parser = wordStack.Peek();
                //int count = wordStack.Count();
                //for (int num = 0; num < count; num++ )
                //{
                if (parser != null && parser.Type == SqlServerStackType.CREATETABLE_PARENTHESIS)
                {
                    wordStack.Pop();
                    isCommaAttribute = true;
                }
                else
                {
                    wordStack.Pop();
                }
                if (doStatus == SqlServerStatus.REQUIRE_ATTRIBUTE_LENGTH_DATATYPE)
                {
                    doStatus = SqlServerStatus.REQUIRE_ATTRIBUTE_OPTION;
                }
                else 
                {
                        //doTag = SqlServerStatus.UNKNOWN;
                        //doStatus = SqlServerStatus.UNKNOWN;
                }
            }
        }

        private void DoPkAttributeTag(DDLWord word)
        {

            if(word.Word == "(")
            {
                ParserStack parser = new ParserStack();
                parser.Word = word;
                parser.Type = SqlServerStackType.CREATEPRIMARYKEY_PARENTHESIS;
                wordStack.Push(parser);
                return;
            }
            else if (word.Word == ")")
            {
                ParserStack check = new ParserStack();
                check = wordStack.Peek();
                if (check.Type == SqlServerStackType.CREATEPRIMARYKEY_PARENTHESIS)
                {
                    wordStack.Pop();
                    check = wordStack.Peek();
                    if (check.Type == SqlServerStackType.CREATEPRIMARYKEY_PARENTHESIS)
                    {
                        doStatus = SqlServerStatus.SCRIPT_ATTRIBUTE;
                        isON = false;
                    }
                    if (check.Type == SqlServerStackType.CREATETABLE_PARENTHESIS)
                    {
                        wordStack.Pop();
                        ParserStack checkCreate = new ParserStack();
                        checkCreate = wordStack.Peek();
                        if (checkCreate.Word.Word == SqlServerTerm.CREATE)
                        {
                            wordStack.Pop();
                            currentClass = new ClassSchema();
                            currentClass.Attributes = new List<AttributeSchema>();
                            doTag = SqlServerStatus.UNKNOWN;
                            doStatus = SqlServerStatus.UNKNOWN;
                        }
                    }
                    return;
                }
                
            }
                string[] nameList = word.Word.Split('.');
                int numName = nameList.Length;

                string attributeName = nameList[numName - 1];

                // delete '[' and ']'
                var removeList = new string[] { "[", "]" };
                foreach (var removeChar in removeList)
                {
                    attributeName = attributeName.Replace(removeChar, string.Empty);
                }

                if (attributeName.Length <= 0)
                {
                    errorMessage.Add("Error : TABLE name is empty : Line:" + word.LineNumber + " Offset:" + word.LineOffset);
                    return;
                }
                else
                {
                    List<AttributeSchema> listAttribute = currentClass.Attributes;
                    foreach (var name in listAttribute)
                    {
                        if (name.Name == attributeName)
                        {
                            name.Pk = true;
                        }
                    }
                }
            
        }

        private void DoCreateAlterTableNameTag(DDLWord word)
        {

            string[] nameList = word.Word.Split('.');
            int numName = nameList.Length;

            string tableName = nameList[numName - 1];

            // delete '[' and ']'
            var removeList = new string[] { "[", "]" };
            foreach (var removeChar in removeList)
            {
                tableName = tableName.Replace(removeChar, string.Empty);
            }

            if (tableName.Length <= 0)
            {
                errorMessage.Add("Error : TABLE name is empty : Line:" + word.LineNumber + " Offset:" + word.LineOffset);
                return;
            }
            else
            {
                //currentClass.ClassName = tableName;
                foreignKeyClassName = tableName;
                doStatus = SqlServerStatus.REQUIRE_ALTER_OPTION;
            }

        }

        private void DoForigntAttributeTag(DDLWord word)
        {

            if (word.Word == "(")
            {
                ParserStack parser = new ParserStack();
                parser.Word = word;
                parser.Type = SqlServerStackType.CREATE_FOREIGNKEY_PARENTHESIS;
                wordStack.Push(parser);
                return;
            }
            else if (word.Word == ")")
            {
                ParserStack check = new ParserStack();
                check = wordStack.Peek();
                if (check.Type == SqlServerStackType.CREATE_FOREIGNKEY_PARENTHESIS)
                {
                    wordStack.Pop();
                    if (wordStack.Peek().Type == SqlServerStackType.CREATE_FOREIGNKEY_PARENTHESIS)
                    {
                        doTag = SqlServerStatus.UNKNOWN;
                        doStatus = SqlServerStatus.UNKNOWN;
                        isON = false;
                    }
                    else
                    {
                        wordStack.Pop();
                        doTag = SqlServerStatus.UNKNOWN;
                        doStatus = SqlServerStatus.UNKNOWN;
                    }
                        return;
                }

            }
            string[] nameList = word.Word.Split('.');
            int numName = nameList.Length;

            string attributeName = nameList[numName - 1];

            // delete '[' and ']'
            var removeList = new string[] { "[", "]" };
            foreach (var removeChar in removeList)
            {
                attributeName = attributeName.Replace(removeChar, string.Empty);
            }

            if (attributeName.Length <= 0)
            {
                errorMessage.Add("Error : TABLE name is empty : Line:" + word.LineNumber + " Offset:" + word.LineOffset);
                return;
            }
            else
            {
                ClassSchema processClass = null;
                
                foreach(var classSchema in result)
                {
                    if (classSchema.ClassName == foreignKeyClassName)
                    {
                        processClass = classSchema;
                        break;
                    }

                }

                if (processClass == null)
                {
                    return;
                }
                List<AttributeSchema> listAttribute = processClass.Attributes;
                foreach (var name in listAttribute)
                {
                    if (name.Name == attributeName)
                    {
                        processClass.Attributes.Remove(name);
                        return;
                    }
                }
            }

        }

        private void DoLengthDataTypeTag(DDLWord word)
        {
            if (word.TerminatorType == SqlServerTerminatorType.OPEN_PARENTHESIS)
            {
                isOpenParenthesis = true;
                ParserStack parser = new ParserStack();
                parser.Word = word;
                parser.Type = SqlServerStackType.CREATE_LENGTHDATATYPE_PARENTHESIS;
                wordStack.Push(parser);
            }
            if ((word.TerminatorType == SqlServerTerminatorType.CLOSE_PARENTHESIS)&&isOpenParenthesis)
            {
                int n;
                int length;
                isNumber = int.TryParse(word.Word,out n);
                if (isNumber)
                {
                    length = Convert.ToInt32(word.Word);
                }
                else
                {
                        length = dataValueLookup.GetType(word);
                    
                }
                currentAttribute.DataLength = length;
                doStatus = SqlServerStatus.REQUIRE_ATTRIBUTE_OPTION;
            }
        }

        private void DoAutoIncrementOptionTag(DDLWord word)
        {
            if (word.Word == SqlServerTerminator.CLOSE_PARENTHESIS)
            {
                currentAttribute.AutoIncrement = true;
                doStatus = SqlServerStatus.REQUIRE_ATTRIBUTE_OPTION;
            }
        }

       

        private void DoReturnTag(DDLWord word)
        {
            if ((doTag==SqlServerStatus.TAG_ATTRIBUTE) && isCommaAttribute)
            {
                currentClass.Attributes.Add(currentAttribute);
                currentAttribute = new AttributeSchema();
                doTag = SqlServerStatus.TAG_ATTRIBUTE;
                doStatus = SqlServerStatus.REQUIRE_ATTRIBUTE_NAME;
                isCommaAttribute = false;
            }
            if((doTag==SqlServerStatus.TAG_ATTRIBUTE) && doStatus == SqlServerStatus.REQUIRE_ATTRIBUTE_NAME)
            {
                ParserStack parser = new ParserStack();
                parser = wordStack.Peek();
                if (parser.Word.TerminatorType == SqlServerTermType.CREATE)
                {
                    if (currentAttribute.Name != null)
                    {
                        currentClass.Attributes.Add(currentAttribute);
                        currentAttribute = new AttributeSchema();
                        wordStack.Pop();
                        currentClass = new ClassSchema();
                        currentClass.Attributes = new List<AttributeSchema>();
                        doTag = SqlServerStatus.UNKNOWN;
                        doStatus = SqlServerStatus.UNKNOWN;
                    }
                }
            }
            if (isOpenLineComment)
            {
                isOpenLineComment = false;
            }
        }
    }
}
